package com.songlanyun.modules.order.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.songlanyun.common.drive.RootEntity;
import com.songlanyun.common.enums.GoodsConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.utils.custom.DateCustomUtils;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyTeam;
import com.songlanyun.modules.marketing.groupbuy.entity.GroupBuyTeamMember;
import com.songlanyun.modules.marketing.groupbuy.service.GroupBuyTeamMemberService;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.order.service.OrderReceiptService;
import com.songlanyun.modules.order.service.OrderSelfTakeService;
import com.songlanyun.modules.order.service.SaleServiceOrderContactsService;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.rabbitmq.util.SpringContextUtil;
import com.songlanyun.modules.ship.entity.OrderPackage;
import com.songlanyun.modules.ship.service.OrderPackageService;
import com.songlanyun.modules.shop.entity.ShopEntity;
import com.songlanyun.modules.shop.service.ShopService;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 销售系统中的主订单
 *
 * @author lubo
 * @email sunlightcs@gmail.com
 * @date 2020-11-16 14:14:42
 */
@Data
@TableName("yxt_sale_order")
public class Order extends RootEntity<Long,Order> implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 *
	 */
	@TableId
	private Long id;

	//是否核销
	private Boolean writeOff;
	/**
	 *
	 */
	@NotBlank(message = "订单编号不能为空")
	@Length(min = 10, max = 50, message = "订单编号长度在10-50个字")
	private String orderCode;

	/**
	 * 订单所属店铺id
	 */
	@NotNull(message = "订单所属店铺id不能为空")
	private Long shopId;



	/**
	 * 所属店铺名称
	 */
	@NotBlank(message = "订单所属店铺名称不能为空")
	private String shopName;
	/**
	 * 订单来源商家店铺id
	 */
	@NotNull(message = "订单来源商家店铺id不能为空")
	private Long sourceShopId;
	/**
	 * 订单来源商家店铺名称
	 */
	@NotBlank(message = "订单来源商家店铺名称不能为空")
	private String sourceShopName;
	/**
	 * 是否是代销订单
	 */
	private Boolean proxy;
	/**
	 * 下单会员
	 */
	@NotNull(message = "下单会员不能为空")
	private Long userId;

	/**
	 * 会员手机号
	 */
	@NotBlank(message = "下单会员手机号不能为空")
	private String mobile;
	/**
	 * 出货方式（0物流，1自提，2预约）
	 */
	private OrderConstant.ShipmentMode shipmentMode;

	/**
	 * 实际计算得到的物流费用(合计)
	 */
	private BigDecimal shouldFreight;
	/**
	 * 真实的物流费用
	 */
	private BigDecimal realFreight;


	/**
	 * 商品总数量
	 */
	private Integer goodsNumber;

	/**
	 * 原商品总价
	 */
	private BigDecimal originalGoodsAmount;

	/**
	 * 实际商品总费用
	 */
	private BigDecimal goodsAmount;


	/**
	 * 会员折扣优惠的费用（如果商品下单改价，也是这个）
	 * @return
	 */
	public BigDecimal getDiscountAmount()
	{
		return MathUtils.subtract(originalGoodsAmount,goodsAmount);
	}
	/**
	 * 总成本
	 */
	private BigDecimal totalCost;
	/**
	 * 总费用(包含运费)
	 */
	private BigDecimal totalAmount;
	/**
	* 总优惠
	*/
	private BigDecimal totalReduced;

	/**
	 * 首单优惠多少钱
	 */
	private BigDecimal firstOrderReduced;

	/**
	 * 是否积分兑换订单
	 */
	private Boolean exchange;
	/**
	 * 订单使用总积分
	 */
	private BigDecimal totalPoint;

	/**
	 * 是否是服务体系商品
	 */
	private Boolean serviceSystemGoods=false;

	/**
	 * 购物完成赠送积分
	 */
	private BigDecimal finalGiveBackPoint;

	/**
	 * 购物完成赠送贡献值
	 */
	private BigDecimal finalConsumptionValue;

	/**
	 * 支付方式（0余额，1微信，2支付宝）
	 */
	private OrderConstant.PayMode payMode;
	/**
	 * 会员下单时的订单备注
	 */
	private String userRemark;
	/**
	 * 商家备注
	 */
	private String businessRemark;
	/**
	 * 商家为订单设置重要级别(1-5级)
	 */
	private Integer importance = 1;
	/**
	 * 下单会员所在商家等级编码
	 */
	private String userRoleCode;
	/**
	 * 下单会员所在商家等级名称
	 */
	private String userRoleName;

	/**
	 * 0系统自动,1 微信小程序，2 APP（订单来源）
	 */
	private OrderConstant.ChannelType channelType;

	/**
	 * 支付是否过期
	 */
	private Boolean expired = false;
	/**
	 * 支付过期时间（时间戳）
	 */
	private Long expiredTime;
	public void  setExpiredTime(Long expiredTime)
	{
		this.expiredTime = expiredTime;
		this.formatExpiredTime = DateCustomUtils.formatToDateTimeString(expiredTime);
	}

	@TableField(exist = false)
	private String formatExpiredTime;
	/**
	 * 下单时间（时间戳）
	 */
	private Long orderTime;
	public void  setOrderTime(Long orderTime)
	{
		this.orderTime = orderTime;
		this.formatOrderTime = DateCustomUtils.formatToDateTimeString(orderTime);
	}
	@TableField(exist = false)
	private String formatOrderTime;
	/**
	 * 支付时间(时间戳)
	 */
	private Long payTime;
	public void  setPayTime(Long payTime)
	{
		this.payTime = payTime;
		this.formatPayTime = DateCustomUtils.formatToDateTimeString(payTime);
	}
	@TableField(exist = false)
	private String formatPayTime;
	/**
	 * 聚合支付订单号
	 */
	@NotBlank(message = "聚合支付订单号不能为空")
	private String payOrderCode;


	/**
	 * 商品分区特征(0普通商品,1激活区商品)
	 */
	private GoodsConstant.AreaFeature areaFeature;

	/**
	 * 聚合支付订单id
	 */

	@NotNull(message = "聚合支付订单id不能为空")
	private Long payOrderId;

	@TableField(exist = false)
	@JsonIgnore
	private PayOrder payOrder;
	public PayOrder loadPayOrder()
	{
		if(payOrder == null)
		{
			PayOrderService payOrderService = (PayOrderService) SpringContextUtil.getBean("payOrderService");
			payOrder = payOrderService.getById(this.getPayOrderId());
		}
		return payOrder;

	}



	/**
	 * 自动备货的最后时间
	 */
	private Long autoStockUpLastTime;
	public void  setAutoStockUpLastTime(Long autoStockUpLastTime)
	{
		this.autoStockUpLastTime = autoStockUpLastTime;
		this.formatAutoStockUpLastTime = DateCustomUtils.formatToDateTimeString(autoStockUpLastTime);
	}
	@TableField(exist = false)
	private String formatAutoStockUpLastTime;

	/**
	 * 最后的发货时间（时间戳）（商家发货时间）
	 */
	private Long lastShipTime;
	public void  setLastShipTime(Long lastShipTime)
	{
		this.lastShipTime = lastShipTime;
		this.formatLastShipTime = DateCustomUtils.formatToDateTimeString(lastShipTime);
	}
	@TableField(exist = false)
	private String formatLastShipTime;
	/**
	 * 最后的收货时间（时间戳）（会员收货时间）
	 */
	private Long lastReceiptTime;
	public void  setLastReceiptTime(Long lastReceiptTime)
	{
		this.lastReceiptTime = lastReceiptTime;
		this.formatLastReceiptTime = DateCustomUtils.formatToDateTimeString(lastReceiptTime);
	}
	@TableField(exist = false)
	private String formatLastReceiptTime;

	/**
	 * 主订单交易完成时间
	 */
	private Long completeTime;
	public void  setCompleteTime(Long completeTime)
	{
		this.completeTime = completeTime;
		this.formatCompleteTime = DateCustomUtils.formatToDateTimeString(completeTime);
	}
	@TableField(exist = false)
	private String formatCompleteTime;

	/**
	 * 主订单交易关闭时间(也是封单时间)
	 */
	private Long closeTime;
	public void  setCloseTime(Long closeTime)
	{
		this.closeTime = closeTime;
		this.formatCloseTime = DateCustomUtils.formatToDateTimeString(closeTime);
	}
	@TableField(exist = false)
	private String formatCloseTime;

	/**
	 * 营销活动内类型(0无活动，1秒杀，2拼团）
	 */
	private Integer marketingType;

	//活动id
	private Long activityId;
	//活动标题
	private String activityTitle;
	//活动发起信息id(如果是限时折扣和首单优惠活动，其为0，如果是拼团其为发起的团Id
	private Long sponsorActivityId=0L;

	/**
	 * 交易状态（0已下单,待支付，1待发货（待备货），2,"部分发货",3,"待收货（待自提）"，4,"部分收货",5交易完成,6关闭
	 */
	private OrderConstant.TransactionStatus transactionStatus;
	/**
	 0未支付 1支付成功，但业务发生异常需要发起退款 2支付成功，但业务发生异常自款成功 3支付成功，但业务发生异常退款失败 4支付失败 5已支付(已支付成功)
	 */
	private OrderConstant.PaymentStatus paymentStatus;


	/**
	 * 0未关闭,1用户撤销关闭,2商家撤销关闭,3支付过期关闭,4退退款成功,5支付成功,但条件已经不允许购买,发生自动退款关闭，6自提过期
	 */
	private OrderConstant.CloseMode closeMode;
	/**
	 * 0未发货，1部分发货，2已发货
	 */
	private OrderConstant.ShipStatus shipStatus;

	/**
	 * 0未使用，1部分已使用，2已全部使用
	 */
	private OrderConstant.UseStatus useStatus;
	/**
	 * 0，未收货，1部分收货，2已收货
	 */
	private OrderConstant.ReceiptStatus receiptStatus;
	/**
	 * 0用户未评，1用户部分已评，2全部已评
	 */
	private OrderConstant.CommentStatus commentStatus;
	/**
	 * 订单是否已起效（如团购订单只有团建成才起效，才可以发货）
	 */
	private Boolean effective;
	/**
	 * 0没有，1仅退款,2退款退货
	 */
	private OrderConstant.RightsType rightsType;
	/**
	 * 订单的维权状态（0没有，1维权中，2完成）
	 */
	private OrderConstant.RightsStatus rightsStatus;

	/**
	 * 订单类型（0充值 1消费订单，2服务订单）
	 */
	private OrderConstant.OrderType orderType;
	/**
	 * 是否关闭（封单也是关闭）
	 */
	private Boolean end;


	@TableField(fill = FieldFill.INSERT)
	private Date createTime;
	/**
	 *
	 */
	@TableField(fill = FieldFill.INSERT_UPDATE)
	private Date updateTime;

	@TableLogic
	private Integer deleted;



	/**
	 * 我的平台优惠券Id
	 */
	private Long platformMyCouponId = 0L;
	/**
	 * 平台优惠券Id
	 */
	private Long platformCouponId = 0L;

	/**
	 * 平台优惠券名称
	 */
	private String platformCouponName = "无可使用券";

	/**
	 * 平台优惠券面额
	 */
	private BigDecimal platformCouponFaceValue = BigDecimal.ZERO;

	/**
	 * 平台券分摊多少钱
	 */
	private BigDecimal platformCouponSharing = BigDecimal.ZERO;

	/**
	 * 我的店铺优惠券Id
	 */
	private Long shopMyCouponId = 0L;
	/**
	 * 店铺优惠券Id
	 */
	private Long shopCouponId = 0L;

	/**
	 * 店铺优惠券名称
	 */
	private String shopCouponName = "无可使用券";

	/**
	 * 店铺优惠券面额
	 */
	private BigDecimal shopCouponFaceValue = BigDecimal.ZERO;

	/**
	 * 店铺优惠券实际优惠多少(对于支付订单，店铺订单，实际的商品子订单)
	 */
	private BigDecimal shopCouponResultValue = BigDecimal.ZERO;

	/**
	 * 主订单下面的子订单
	 */
	@TableField(exist = false)
	private List<ChildOrder> childOrderList;


	/**
	 *  是否是第三方商品
	 */
	private Boolean third;

	/**
	 *  是否是后台生成的订单(0不是，1是)
	 */
	private Boolean adminOrder = false;


	@JsonIgnore
	public List<ChildOrder> getChildOrderList(boolean load)
	{
		if(load || childOrderList == null)
		{
			ChildOrderService childOrderService = (ChildOrderService) SpringContextUtil.getBean("childOrderService");
			childOrderList = childOrderService.list(new LambdaQueryWrapper<ChildOrder>().eq(ChildOrder::getOrderId, this.getId()));
		}
		return childOrderList;
	}

	/**
	 * 订单的收件人信息
	 */
	@TableField(exist = false)
	private OrderReceipt receipt;

	public OrderReceipt loadOrderReceipt()
	{
		OrderReceiptService service = (OrderReceiptService) SpringContextUtil.getBean("orderReceiptService");
		if(receipt == null)
		{
			receipt  = service.getOne(new LambdaQueryWrapper<OrderReceipt>()
					.eq(OrderReceipt::getOrderId, this.getId())
					.last("limit 1"));
		}
		return receipt;
	}

	/**
	 * 订单的自提人信息
	 */
	@TableField(exist = false)
	private OrderSelfTake selfTake;
	public OrderSelfTake loadOrderSelfTake()
	{
		OrderSelfTakeService service = (OrderSelfTakeService) SpringContextUtil.getBean("orderSelfTakeService");
		if(selfTake == null)
		{
			selfTake  = service.getOne(new LambdaQueryWrapper<OrderSelfTake>()
					.eq(OrderSelfTake::getOrderId, this.getId())
					.last("limit 1"));

		}
		return selfTake;
	}

	@TableField(exist = false)
	private GroupBuyTeam team;

	public GroupBuyTeam loadGroupBuyTeam()
	{
		if(this.getMarketingType()==2)
		{
			if(team==null)
			{
				GroupBuyTeamMemberService groupBuyTeamMemberService = (GroupBuyTeamMemberService)SpringContextUtil.getBean("groupBuyTeamMemberService");
				GroupBuyTeamMember member = groupBuyTeamMemberService.getByOrderIdAndUserId(this.id, this.userId);
				team = member.loadGroupBuyTeam();
			}
		}
		return team;
	}


	/**
	 * 服务订单联系人
	 */
	@TableField(exist = false)
	private SaleServiceOrderContacts serviceOrderContacts;
	@JsonIgnore
	public SaleServiceOrderContacts loadServiceOrderContacts()
	{
		SaleServiceOrderContactsService service = (SaleServiceOrderContactsService) SpringContextUtil.getBean("saleServiceOrderContactsService");
		if(serviceOrderContacts == null)
		{
			serviceOrderContacts  = service.loadByOrderId(this.getId());
		}
		return serviceOrderContacts;
	}

	@TableField(exist = false)
	private OrderPackage orderPackage;
	public OrderPackage loadOrderPackage()
	{
		OrderPackageService service = (OrderPackageService) SpringContextUtil.getBean("orderPackageService");
		if(orderPackage == null)
		{
			orderPackage  = service.loadByOrderId(this.getId(),false);
		}
		return orderPackage;
	}

	@Override
	public Long getIdentity() {
		return getId();
	}

	@TableField(exist = false)
	private ShopEntity shop;
	public ShopEntity loadShop()
	{
		ShopService service = (ShopService) SpringContextUtil.getBean("yxtShopService");
		if(shop == null)
		{
			shop  = service.loadShopBy(this.getShopId(),false);
		}
		return shop;
	}

	/**
	 * 商家是否可以操作
	 */
	@TableField(exist = false)
	private Boolean operator;
	public Boolean loadOperator(Long shopId)
	{
		operator =  true;
		if(this.getProxy() && !shopId.equals(getShopId()))
		{
			operator =  false;
		}
		return operator;
	}

	public Long getNowMillis(){
		return System.currentTimeMillis();
	}

	/**
	 * 真实姓名
	 */
	private String realName;
	/**
	 * 身份证号
	 */
	private String idNo;

}
